#include "my_account.h"

My_account::~My_account()
{
    shutdown();
}

void My_account::onRegState(OnRegStateParam &prm)
{
    AccountInfo ai = getInfo();
    cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=")
         << prm.code << endl;
}

void My_account::onIncomingCall(OnIncomingCallParam &iprm)
{
    qDebug()<<"A Call is coming.************************************************************************";
    incomIprm = iprm;
    incomCall = new MyCall(*this,iprm.callId,this);

    CallOpParam prm;
    prm.statusCode = PJSIP_SC_TRYING;
    try {
        incomCall->answer(prm);
    } catch (const pj::Error& e) {
        qDebug() << "Answer error: " << e.info().c_str();
    }

    prm.statusCode = PJSIP_SC_RINGING;
    try {
        incomCall->answer(prm);
    } catch (const pj::Error& e) {
        qDebug() << "Answer error: " << e.info().c_str();
    }

    connect(incomCall, &MyCall::EOnCallStateOver,this, &My_account::EOnCallStateOverChange);
    connect(incomCall, &MyCall::EOnCallMediaState,this, &My_account::EOnCallMediaStateChange);
    connect(incomCall, &MyCall::EOnInstantMessage,this, &My_account::EOnInstantMessageChange);

    emit incomingCallSignal(&incomIprm);
}

void My_account::UseRemoteUrlMakeACall(string remoteUrl)
{
    qDebug()<<"UseRemoteUrlMakeACall going.remoteUrl ="<<QString::fromStdString(remoteUrl);
    CallOpParam prm(true); // Use default call settings
    if(callUp == nullptr)
    {
        //创建通话
        callUp = new MyCall(*this,PJSUA_INVALID_ID,this);
        callUp->makeCall(remoteUrl, prm);
        // 将incomCall的信号连接到My_account的信号
        connect(callUp, &MyCall::EOnCallStateOver,this, &My_account::EOnCallStateOverChange);
        connect(callUp, &MyCall::EOnCallMediaState,this, &My_account::EOnCallMediaStateChange);
        connect(callUp, &MyCall::EOnInstantMessage,this, &My_account::EOnInstantMessageChange);
    }
    else
    {
        qDebug()<<"callUp is exist.";
    }
}

void My_account::sendInstantMessageToRemote(string message)
{
    MyCall** callTemp;
    callTemp = checkHaveCallIsActiveAndBackPtr();

    if(callTemp == nullptr)
    {
        return;
    }
    else
    {
        MyCall* activeCall = *callTemp;

        SendInstantMessageParam prm;
        prm.content = message;

        activeCall->sendInstantMessage(prm);
    }
}

void My_account::answerReceiveCall(void)
{
    CallOpParam prm;
    prm.statusCode = PJSIP_SC_OK;

    if(incomCall == nullptr)
    {
        qDebug() << "no call can answer.";
        return;
    }
    else if(!incomCall->isActive())
    {
        qDebug() << "incomCall is unActive.";
        return;
    }

    try {
        incomCall->answer(prm);
    } catch (const pj::Error& err) {
        qDebug() << "answerReceiveCall error: " << err.info().c_str() << endl;
    }
}

void My_account::hangUpCall(void)
{
    CallOpParam prm;
    MyCall** callTemp;

    callTemp = checkHaveCallIsActiveAndBackPtr();

    if(callTemp == nullptr)
    {
        return;
    }
    else
    {
        MyCall* activeCall = *callTemp;
        prm.reason = "user hangup by himself";
        prm.statusCode = PJSIP_SC_DECLINE;
        activeCall->hangup(prm); // 调用挂断方法
        *callTemp = nullptr;
    }
}

bool My_account::HoldCall()
{
    CallOpParam prm;

    MyCall** callTemp = nullptr;
    callTemp = checkHaveCallIsActiveAndBackPtr();
    MyCall* activeCall = *callTemp;

    if(callTemp == nullptr)
    {
        return false;
    }
    else
    {
        prm.reason = "user hold by himself";
        activeCall->setHold(prm);
        return true;
    }
}

bool My_account::ReinviteCall()
{
    CallOpParam prm;

    MyCall** callTemp = nullptr;
    callTemp = checkHaveCallIsActiveAndBackPtr();
    MyCall* activeCall = *callTemp;

    if(callTemp == nullptr)
    {
        return false;
    }
    else
    {
        prm.reason = "user reinvite by himself";
        activeCall->reinvite(prm);
        return true;
    }
}

void My_account::startPlayWavToRemote(void)
{
    MyCall** callTemp;

    callTemp = checkHaveCallIsActiveAndBackPtr();

    if(callTemp == nullptr)
    {
        return;
    }
    else
    {
        MyCall* activeCall = *callTemp;
        activeCall->startSendMusic();
    }
}

void My_account::stopPlayWavToRemote(void)
{
    MyCall** callTemp;

    callTemp = checkHaveCallIsActiveAndBackPtr();

    if(callTemp == nullptr)
    {
        return;
    }
    else
    {
        MyCall* activeCall = *callTemp;
        activeCall->stopSendMusic();
    }
}

//此函数有一个问题，当callUp和incomCall同时存在时会优先返回callUp。
MyCall** My_account::checkHaveCallIsActiveAndBackPtr(void)
{
    if(callUp == nullptr && incomCall == nullptr)
    {
        qDebug()<<"You don't have a call.";
        return nullptr;
    }
    else if(callUp != nullptr && callUp->isActive())
    {
        return &callUp;
    }
    else if(incomCall != nullptr && incomCall->isActive())
    {
        return &incomCall;
    }
    else
    {
        qDebug()<<"no call is active.";
        return nullptr;
    }
}

string My_account::getRemoteUrl(void)
{
    string retString;
    MyCall** callTemp;

    callTemp = checkHaveCallIsActiveAndBackPtr();

    if(callTemp == nullptr)
    {
        retString = "error";
    }
    else
    {
        MyCall* activeCall = *callTemp;
        retString = activeCall->getInfo().remoteUri;
    }

    return retString;
}

void My_account::cleanExistCall(void)
{
    if(callUp == nullptr && incomCall == nullptr)
    {
        qDebug()<<"You don't have a call.";
        return;
    }

    if(callUp != nullptr)
    {
        callUp = nullptr;
    }

    if(incomCall != nullptr)
    {
        incomCall = nullptr;
    }
}

